defprocess_payment(user,amount)# Log the payment details including sensitive informationputs"Payment processed for user #{user.name} with amount #{amount}"# Process the payment# ...end
✅ compliance
require'logger'defprocess_payment(user,amount)# Initialize a logger with appropriate settingslogger=Logger.new('payment.log')# Log a message without sensitive informationlogger.info("Payment processed for user with ID #{user.id}")# Process the payment# ...end
Insertion of Sensitive Information Into Sent Data
🐞 non-compliance
defsend_data(user,data)# Include sensitive information in the sent datarequest_body={user:user,data:data}HTTP.post('https://api.example.com/data',body:request_body.to_json)end
✅ compliance
defsend_data(user,data)# Exclude sensitive information from the sent datarequest_body={data:data}HTTP.post('https://api.example.com/data',body:request_body.to_json)end
Cross-Site Request Forgery (CSRF)
🐞 non-compliance
# Noncompliant codeget'/transfer_funds'doamount=params[:amount]recipient=params[:recipient]# Transfer funds logic here# ...end
# Noncompliant codeget'/search'doquery=params[:query]"<h1>Search Results for #{query}</h1>"end
✅ compliance
# Compliant coderequire'rack/utils'get'/search'doquery=params[:query]sanitized_query=Rack::Utils.escape_html(query)"<h1>Search Results for #{sanitized_query}</h1>"end
SQL Injection
🐞 non-compliance
# Noncompliant codeget'/search'doquery=params[:query]result=DB.execute("SELECT * FROM products WHERE name = '#{query}'")# Process and return search resultsend
✅ compliance
# Compliant codeget'/search'doquery=params[:query]result=DB.execute("SELECT * FROM products WHERE name = ?",query)# Process and return search resultsend
# Compliant codeget'/download'dofilename=params[:filename]sanitized_filename=File.basename(filename)file_path=File.join("/path/to/files/",sanitized_filename)ifFile.exist?(file_path)&&File.file?(file_path)send_file(file_path,disposition:'attachment')elsehalt404,'File not found'endend
Generation of Error Message Containing Sensitive Information
🐞 non-compliance
# Noncompliant codeget'/user/:id'douser_id=params[:id]user=User.find(user_id)ifuser.nil?error_message="User with ID #{user_id} not found"raiseStandardError,error_messageend# Process and return user dataend
✅ compliance
# Compliant codeget'/user/:id'douser_id=params[:id]user=User.find(user_id)ifuser.nil?error_message="User not found"raiseStandardError,error_messageend# Process and return user dataend
# Noncompliant codedefprocess_user_input(user_input)ifuser_input.admin?grant_admin_privileges()end# Process user inputend
✅ compliance
# Compliant codedefprocess_user_input(user_input,user_role)ifuser_role=='admin'grant_admin_privileges()end# Process user inputend
Insufficiently Protected Credentials
🐞 non-compliance
# Noncompliant codeAPI_KEY='my_api_key'DB_PASSWORD='my_db_password'# Code that uses the API key and database password
✅ compliance
# Compliant coderequire'openssl'require'base64'defencrypt_credentials(plaintext)cipher=OpenSSL::Cipher.new('AES-256-CBC')cipher.encryptcipher.key=ENV['ENCRYPTION_KEY']encrypted=cipher.update(plaintext)+cipher.finalBase64.encode64(encrypted)endAPI_KEY=encrypt_credentials('my_api_key')DB_PASSWORD=encrypt_credentials('my_db_password')# Code that uses the encrypted credentials
Restriction of XML External Entity Reference
🐞 non-compliance
# Noncompliant coderequire'nokogiri'xml_data="<user><name>John Doe</name><credit_card>&xxe;</credit_card></user>"doc=Nokogiri::XML(xml_data)# Process XML document
✅ compliance
# Compliant coderequire'nokogiri'xml_data="<user><name>John Doe</name><credit_card>&xxe;</credit_card></user>"doc=Nokogiri::XML(xml_data)do|config|config.nonet# Disable network accessconfig.noblanks# Ignore whitespace nodesconfig.noent# Disable entity expansionend# Process XML document
# Compliant coderequire'net/http'require'openssl'defmake_secure_request(url)uri=URI.parse(url)http=Net::HTTP.new(uri.host,uri.port)http.use_ssl=truehttp.verify_mode=OpenSSL::SSL::VERIFY_PEERhttp.ca_file='/path/to/certificate.crt'# Provide the path to the trusted CA certificateresponse=http.get(uri.request_uri)response.bodyendurl='https://example.com'response=make_secure_request(url)putsresponse
# Compliant coderequire'bcrypt'defauthenticate(username,password)hashed_password=get_hashed_password(username)ifBCrypt::Password.new(hashed_password)==passwordputs'Authentication successful'elseputs'Authentication failed'endenddefget_hashed_password(username)# Retrieve the hashed password associated with the username from a secure storage (e.g., database)# Return the hashed passwordend# Usageauthenticate('admin','guess')# Compliant authentication attempt
Session Fixation
🐞 non-compliance
# Noncompliant coderequire'sinatra'get'/login'dosession[:user_id]=params[:user_id]redirect'/dashboard'endget'/dashboard'do# Access user's data based on session[:user_id]end
✅ compliance
require'sinatra'require'securerandom'enable:sessionsget'/login'dosession.clear# Clear existing session datasession[:user_id]=params[:user_id]session[:session_id]=SecureRandom.uuid# Generate a new session identifierredirect'/dashboard'endget'/dashboard'do# Access user's data based on session[:user_id]end
# Noncompliant coderequire'open-uri'file_url='http://example.com/malicious_code.rb'file_content=open(file_url).read# Process the downloaded file_content
✅ compliance
# Compliant coderequire'open-uri'require'digest'file_url='http://example.com/malicious_code.rb'file_content=open(file_url).readexpected_hash='5f4dcc3b5aa765d61d8327deb882cf99'# Example expected MD5 hashifDigest::MD5.hexdigest(file_content)==expected_hash# File integrity check passed# Process the downloaded file_contentelse# File integrity check failed# Handle the error or reject the downloaded fileend
Deserialization of Untrusted Data
🐞 non-compliance
# Noncompliant codedata=params[:serialized_data]object=Marshal.load(data)# Process the deserialized object
✅ compliance
# Compliant codedata=params[:serialized_data]object=nilbeginobject=YAML.safe_load(data,[Symbol])rescuePsych::Exception=>e# Handle deserialization errorputs"Deserialization error: #{e.message}"end# Process the deserialized object if it was successfully loadedifobject# Process the deserialized objectelse# Handle the error or reject the deserialized dataend
# Compliant coderequire'logger'logger=Logger.new('application.log')deftransfer_funds(sender,recipient,amount)ifsender.balance>=amountsender.balance-=amountrecipient.balance+=amountlogger.info("Funds transferred: $#{amount} from #{sender.name} to #{recipient.name}")elselogger.warn("Insufficient funds for transfer: $#{amount} from #{sender.name} to #{recipient.name}")endend
Improper Output Neutralization for Logs
🐞 non-compliance
# Noncompliant codelogger=Logger.new('application.log')deflog_user_activity(user_id,activity)logger.info("User #{user_id} performed activity: #{activity}")end
✅ compliance
# Compliant codelogger=Logger.new('application.log')deflog_user_activity(user_id,activity)sanitized_user_id=sanitize_output(user_id)sanitized_activity=sanitize_output(activity)logger.info("User #{sanitized_user_id} performed activity: #{sanitized_activity}")enddefsanitize_output(input)# Implement output neutralization logic here# For example, remove or escape special characters that could be used for log injectionsanitized_input=input.gsub(/[<>]/,'')# Return the sanitized inputsanitized_inputend
require'open-uri'# Noncompliant codedeffetch_url(url)data=open(url).read# Process the fetched dataend
✅ compliance
require'open-uri'require'uri'# Compliant codedeffetch_url(url)parsed_url=URI.parse(url)ifparsed_url.host=='trusted-domain.com'data=open(url).read# Process the fetched dataelse# Handle the case of an untrusted or restricted domainputs'Access to the specified domain is not allowed.'endend